broadway: Implement pointer query_status
authorAlexander Larsson <alexl@redhat.com>
Fri, 11 Mar 2011 13:56:31 +0000 (14:56 +0100)
committerAlexander Larsson <alexl@redhat.com>
Fri, 11 Mar 2011 13:56:31 +0000 (14:56 +0100)
gdk/broadway/broadway.c
gdk/broadway/broadway.h
gdk/broadway/broadway.js
gdk/broadway/gdkdevice-broadway.c
gdk/broadway/gdkdisplay-broadway.h
gdk/broadway/gdkeventsource.c

index 40a93b47fd7b06ebe5679fe724f6799ac6f5e32e..b393879d2a9da9576f970746394ca823b8cb0555 100644 (file)
@@ -643,6 +643,24 @@ broadway_output_copy_rectangles (BroadwayOutput *output,  int id,
   free (buf);
 }
 
+guint32
+broadway_output_query_pointer (BroadwayOutput *output, int id)
+{
+  char buf[HEADER_LEN + 3];
+  guint32 serial;
+  int p;
+
+  serial = output->serial;
+  p = write_header (output, buf, 'q');
+  append_uint16 (id, buf, &p);
+
+  assert (p == sizeof (buf));
+
+  broadway_output_write (output, buf, sizeof (buf));
+
+  return serial;
+}
+
 void
 broadway_output_new_surface(BroadwayOutput *output,  int id, int x, int y, int w, int h)
 {
index 8c8589ea5e730603fdd78be7e7625a389b4b8d14..b0d3c2a61f72bb20fff828bc85234e581159af23 100644 (file)
@@ -55,3 +55,5 @@ void            broadway_output_copy_rectangles (BroadwayOutput *output,
                                                 int             n_rects,
                                                 int             dx,
                                                 int             dy);
+guint32         broadway_output_query_pointer   (BroadwayOutput *output,
+                                                int id);
index c0f17f77c8db6f9552139f90fa43f962717cdc2f..08c0fcb938482c394e323f20fa6d402791c4fe25 100644 (file)
@@ -64,6 +64,8 @@ function createXHR()
 }
 
 var last_serial = 0;
+var last_x = 0;
+var last_y = 0;
 var surfaces = {};
 var outstanding_commands = new Array();
 var input_socket = null;
@@ -240,6 +242,13 @@ function handleCommands(cmd_obj)
        context.restore();
         break;
 
+      case 'q': // Query pointer
+        var id = base64_16(cmd, i);
+        i = i + 3;
+
+       send_input ("q", [last_x, last_y]);
+       break;
+
       default:
         alert("Unknown op " + command);
     }
@@ -284,16 +293,24 @@ function send_input(cmd, args)
   }
 }
 
+function update_positions_from_event(ev) {
+    last_x = ev.pageX;
+    last_y = ev.pageY;
+}
+
 function on_mouse_move (ev) {
-  send_input ("m", [get_surface_id(ev), ev.pageX, ev.pageY, ev.timeStamp])
+  update_positions_from_event(ev);
+  send_input ("m", [get_surface_id(ev), last_x, last_y, ev.timeStamp]);
 }
 
 function on_mouse_down (ev) {
-  send_input ("b", [get_surface_id(ev), ev.pageX, ev.pageY, ev.button, ev.timeStamp])
+  update_positions_from_event(ev);
+  send_input ("b", [get_surface_id(ev), last_x, last_y, ev.button, ev.timeStamp]);
 }
 
 function on_mouse_up (ev) {
-  send_input ("B", [get_surface_id(ev), ev.pageX, ev.pageY, ev.button, ev.timeStamp])
+  update_positions_from_event(ev);
+  send_input ("B", [get_surface_id(ev), last_x, last_y, ev.button, ev.timeStamp]);
 }
 
 var last_key_down = 0;
index 0d0aaa9eccd5641e8595a2e793e5a0836052fb73..b222d6854735acd304888689eae7c81b432634c3 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "config.h"
+#include <stdlib.h>
 
 #include "gdkdevice-broadway.h"
 
@@ -152,17 +153,87 @@ gdk_broadway_device_query_state (GdkDevice        *device,
                                 gint             *win_y,
                                 GdkModifierType  *mask)
 {
+  GdkDisplay *display;
+  GdkBroadwayDisplay *broadway_display;
+  GdkWindowImplBroadway *impl;
+  guint32 serial;
+  GdkScreen *screen;
+  char *reply;
+  gint device_root_x, device_root_y;
+
+  if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
+    return FALSE;
+
+  display = gdk_device_get_display (device);
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+  if (root_window)
+    {
+      screen = gdk_window_get_screen (window);
+      *root_window = gdk_screen_get_root_window (screen);
+    }
+
+  if (mask)
+    *mask = 0; /* TODO */
+
+  device_root_x = broadway_display->last_x;
+  device_root_y = broadway_display->last_y;
+
+  if (broadway_display->output)
+    {
+      impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+
+      serial = broadway_output_query_pointer (broadway_display->output, impl->id);
+
+      reply = _gdk_broadway_display_block_for_input (display, 'q', serial);
+
+      if (reply != NULL)
+       {
+         char *p;
+         char cmd;
+         guint32 reply_serial;
+
+         p = reply;
+
+         cmd = *p++;
+         reply_serial = (guint32)strtol(p, &p, 10);
+         p++; /* Skip , */
+
+         device_root_x = strtol(p, &p, 10);
+         p++; /* Skip , */
+         device_root_y = strtol(p, &p, 10);
+         p++; /* Skip , */
+
+         g_free (reply);
+       }
+    }
+
+  /* Fallback when unconnected */
+
   if (root_x)
-    *root_x = 0;
+    *root_x = device_root_x;
   if (root_y)
-    *root_y = 0;
+    *root_y = device_root_y;
   if (win_x)
-    *win_x = 0;
+    *win_x = device_root_y - window->x;
   if (win_y)
-    *win_y = 0;
-  if (mask)
-    *mask = 0;
-  return FALSE;
+    *win_y = device_root_y - window->y;
+  if (child_window)
+    {
+      if (gdk_window_get_window_type (window) == GDK_WINDOW_ROOT)
+       {
+         *child_window = broadway_display->mouse_in_toplevel;
+         if (*child_window == NULL)
+           *child_window = window;
+       }
+      else
+       {
+         /* No native children */
+         *child_window = window;
+       }
+    }
+
+  return TRUE;
 }
 
 static GdkGrabStatus
index 76df17ac2b032b29b0bf329ca86d4d9a8aeeb3ac..a7a07a59929fd17ee7a16a0587ad8dcbdc9e450e 100644 (file)
@@ -56,7 +56,7 @@ struct _GdkBroadwayDisplay
 
   GSource *event_source;
   GdkWindow *mouse_in_toplevel;
-  int last_x, last_y;
+  int last_x, last_y; /* in root coords */
 
   /* Keyboard related information */
   GdkKeymap *keymap;
index 8a6912c4951ff2f2df5bb1f5d631dd801e10a356..78c51ee47dfa6fee7948fe51a9102028318c148b 100644 (file)
@@ -283,9 +283,12 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
        _gdk_windowing_got_event (display, node, event, serial);
       }
 
+    break;
+  case 'q':
+    g_printerr ("Got unexpected query pointer reply w serial %d\n", serial);
     break;
   default:
-    g_print ("Unknown input command %s\n", message);
+    g_printerr ("Unknown input command %s\n", message);
     break;
   }
 }